home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
WINPROGS
/
UPC12BS2.ZIP
/
RNEWS
/
HISTORY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-13
|
14KB
|
423 lines
/*--------------------------------------------------------------------*/
/* h i s t o r y . c */
/* */
/* News history file maintenance for UUPC/extended. */
/* */
/* Written by Mike Lipsie */
/* */
/* The history file */
/* */
/* This file describes and implements the history file. */
/* */
/* The history file is [newsdir]/history and is "added" to by */
/* rnews. It is "pruned" by expire and is used by rnews (to */
/* check that the article has not arrived before), expire (to */
/* find all copies of the article), and rn (to mark as read all */
/* copies of an article.) */
/* */
/* The history file is entirely ASCII. */
/* */
/* The first line is a code that identifies the version level */
/* (so that future versions can automatically upgrade.) For */
/* version one that code is "ZIP1". */
/* */
/* Every line (except the version line) is the record of a */
/* single incoming article. That line is exactly as described */
/* without added spaces or other punctuation. The first field */
/* is the Message-ID including (or added if they don't exist), */
/* the "<" and ">", a space, the date received (dd/mm/yyyy with */
/* days and months being zero filled if necessary), a space, */
/* and the "destination" information. */
/* */
/* The destination information is the Newsgroups: with a colon */
/* and the article number for each group added (article number */
/* zero is used for newsgroups not accepted.) */
/* */
/* For example, if article <123@pyramid> was received on 3 Jan */
/* 1992 and was posted to ba.food, ba.transportation, and */
/* soc.singles and ended up in article 4334, 1234, and 56789 */
/* (respectively), the record would be */
/* */
/* <123@pyramid> 03/01/1992 */
/* ba.food:4334,ba.transportation:1234,soc.singles:56789 */
/* */
/* To speed access into the history file there is a parallel */
/* file history.ndx which contains information where each day's */
/* worth of history records begins. The first line is a */
/* version number and must be the same as that of the history */
/* file. All the other records are the 10 character date code, */
/* a space, and a ten digit location code (right justified, */
/* zero or blank filled.) The location code is the byte */
/* displacement into the history file of the first record with */
/* that date code. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "hlib.h"
#include "timestmp.h"
#include "active.h"
#include "history.h"
/* These variables are used to improve the performance of checking
* for previous existance of an article.
*
* The basic theory of how this feature works is that a file
* (history.dbm) is built with enough information (it is hoped)
* to eliminate 99% (well, most) of the non matching message IDs.
* A check is made when a match is made confiming that the match
* is real. Since most articles are not "re-sends" (all if you
* have only one feed) this won't impose a large overhead.
*
* The information that is used to eliminate unnecessary checks into
* the history file for duplicate messageIDs is the first ten
* characters of the message ID (not including the leading "<"),
* the number of characters in the full ID (including the "<" and ">"),
* a checksum of the full ID (also including the "<" and ">"), and
* the location in the history file of the full ID.
*
* Additionally, an array of MAXbuf (currently 8) buffers of history.dbm
* are maintained in memory to avoid disk I/O.
*
*/
int cur_buff = 0;
int cur_off = 0;
#define MAXbuf 8
char *hb[MAXbuf];
int hb_blk[MAXbuf];
extern FILE *hfile;
FILE *hdbm_file = NULL;
struct perf_elem {
char IDpart[10]; /* The first 10 characters (after the "<") of the message-ID */
char cksum; /* Checksum of the entire ID (including <>) */
char IDlen; /* Number of characters in the ID (including <>) */
long where; /* ftell() in file of actual record */
};
/*--------------------------------------------------------------------*/
/* h i s t o r y _ e x i s t s */
/* */
/* Determine if the history file exists and is a file (instead */
/* of a directory). */
/*--------------------------------------------------------------------*/
boolean history_exists( void )
{
char hfile_name[FILENAME_MAX];
struct stat buff;
mkfilename(hfile_name, E_newsdir, "history");
if ((stat(hfile_name, &buff) == 0) && buff.st_mode & S_IFREG)
return TRUE;
else
return FALSE;
} /* history_exists */
/*--------------------------------------------------------------------*/
/* o p e n _ h i s t o r y */
/* */
/* Open the history file and verify that it is of the correct */
/* version. If any error occurs, NULL is returned. */
/*--------------------------------------------------------------------*/
#ifdef __TURBOC__
#pragma argsused
#endif
FILE *open_history(char *history_date)
{
#ifdef NEXT_RELEASE_MAYBE
char hfile_name[FILENAME_MAX];
FILE *hfile;
FILE *index_file;
char buff[BUFSIZ];
mkfilename(hfile_name, newsdir, "history");
hfile = fopen(hfile_name, "a+b");
if (hfile == NULL) {
printmsg(0,"Unable to open history file");
return hfile;
}
fseek(hfile, 0L, SEEK_SET);
fgets(buff, sizeof(buff), hfile);
buff[strlen(buff)-1] = '\0';
if (buff[strlen(buff)-1] == '\r') buff[strlen(buff)-1] = '\0';
if ((strlen(buff)) != strlen(H_VERSION)) {
printmsg(0, "History version incorrect");
return NULL;
}
if (!equal(buff, H_VERSION)) {
printmsg(0, "History version incorrect");
return NULL;
}
fseek(hfile, 0L, SEEK_END);